package com.itany.corejava.code14_lambda;

import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author 石小俊
 * @date 2023年05月30日 16:48
 */
public class Test06_方法引用 {
    public static void main(String[] args) {
        // 方法引用
        // 对象::实例方法名
        Consumer<String> c = s -> System.out.println(s);
        // 此时发现并没有打印效果
        // 此时本质上是将方法整体赋值给变量c
        // 并没有去执行方法,因此没有打印效果
        // 想要执行方法,通过对象::实例方法名
        c = System.out::println;
        c.accept("Hello Consumer");

        User user = new User();
        Consumer<String> c2 = user::setUsername;
        c2.accept("admin");
        System.out.println(user.getUsername());

        // 如果想要执行get方法,需要选择一个无参的函数式接口
        Supplier<String> s = user::getUsername;
        System.out.println(s.get());
        c.accept(s.get());

        // 类::静态方法名
        System.out.println(User.hello());
        Supplier<String> s2 = User::hello;
        c.accept(s2.get());

        // 类::实例方法名
        Predicate<String> p = "aa"::equals;
        boolean flag = p.test("aa");
        // 此时相当于字符串aa调用了equals方法
        // 断言型接口中方法的参数即为调用的equals方法参数
        // 此时的一个字符串被写死,不太合适
        System.out.println(flag);
        // JDK8中提供了BiPredicate类型,专门用于处理类似的操作
        // 此时的两个泛型分别对应方法的调用者与方法的参数
        // 第一个泛型是调用方法的调用者类型
        // 第二个泛型是方法参数的类型
        // 此时在定义时,无法确定具体的调用者是谁
        // 但是我能知道一定是字符串
        // 此时可以使用类::实例方法名的方式进行定义
        BiPredicate<String, String> p2 = String::equals;
        flag = p2.test("aaa", "aaa");
        System.out.println(flag);
    }
}
